#pragma once
#include <iostream>
#include <string>
using namespace std;
template<class T>
class MyArray
{
public:
    // 构造函数
    MyArray(int capacity);
    // 拷贝构造函数
    MyArray(const MyArray &ma);
    // 析构函数
    ~MyArray();
    // =重载 (链式实现a = b = c)
    MyArray& operator=(const MyArray &ma);
    // 返回容量
    int getCapacity();
    // 返回大小
    int getSize();
    // 尾插法
    void push_back(const T &val);
    // 尾删法
    void pop_back();
    // []重载
    T& operator[](int index);
private:
    T * m_address;
    int m_capacity;
    int m_size;
};
// 构造函数类外实现
template<class T>
MyArray<T>::MyArray(int capacity)
{
    cout << "调用构造函数" << endl;
    this->m_capacity = capacity;
    this->m_address = new T[this->m_capacity];
    this->m_size = 0;
}
// 拷贝构造函数类外实现
template<class T>
MyArray<T>::MyArray(const MyArray &ma)
{
    cout << "调用拷贝构造函数" << endl;
    this->m_capacity = ma.m_capacity;
    this->m_size = ma.m_size;
    this->m_address = new T[this->m_capacity];
    for (int i = 0; i < this->m_size; ++i)
    {
        this->m_address[i] = ma.m_address[i];
    }
}
// 析构函数类外实现
template<class T>
MyArray<T>::~MyArray()
{
    cout << "调用析构函数" << endl;
    if (this->m_address != nullptr)
    {
        delete[] this->m_address;
        this->m_address = nullptr;
    }
}
// =重载类外实现
template<class T>
MyArray<T>& MyArray<T>::operator=(const MyArray<T> &ma)
{
    cout << "=重载" << endl;
    // 先释放自己的原先的内存
    cout << "释放内存" << endl;
    if (this->m_address != nullptr)
    {
        delete[] this->m_address;
        this->m_address = nullptr;
        this->m_capacity = 0;
        this->m_size = 0;
    }
    // 开辟新内存
    cout << "重新分配内存" << endl;
    this->m_capacity = ma.m_capacity;
    this->m_size = ma.m_size;
    this->m_address = new T[this->m_capacity];
    for (int i = 0; i < this->m_size; ++i)
    {
        this->m_address[i] = ma.m_address[i];
    }
    return *this;
}
// 返回容量类外实现
template<class T>
int MyArray<T>::getCapacity()
{
    return this->m_capacity;
}
// 返回大小类外实现
template<class T>
int MyArray<T>::getSize()
{
    return this->m_size;
}
// 尾插法类外实现
template<class T>
void MyArray<T>::push_back(const T &val)
{
    if (this->m_capacity == this->m_size)
    {
        cout << "容量不足" << endl;
        return;
    }
    this->m_address[this->m_size++] = val;
    cout << "尾插数据成功" << endl;
}
// 尾删法类外实现
template<class T>
void MyArray<T>::pop_back()
{
    if (m_size == 0)
    {
        cout << "无元素可删除" << endl;
        return;
    }
    --this->m_size;
    cout << "尾删数据成功" << endl;
}
// []重载类外实现
template<class T>
T& MyArray<T>::operator[](int index)
{
    return this->m_address[index];
}